package com.shopping.handle.impl;

import com.shopping.FruitType;
import com.shopping.GoodsStatus;
import com.shopping.handle.Supermarket;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;

/*
 * @author wdx
 * @desc 模拟超市售卖水果
 * 设计模式 使用建造者模式
 * @date 2023/10/28
 * */
public class FruitSupermarket implements Supermarket {
    private final Shopping shopping;

    private FruitSupermarket(Shopping shopping) {
        this.shopping = shopping;
    }

    //结账方法
    @Override
    public BigDecimal checkout() {
        HashMap<String, Double> shoppingTrolley = shopping.getShoppingTrolley();//获得当前的购物车
        BigDecimal totalAmount = new BigDecimal("0.00");//初始总价格

        for (String fruitName : shoppingTrolley.keySet()) {
            Double weight = shoppingTrolley.get(fruitName);
            Integer price = shopping.getFruitPrice(fruitName);
            assert price >= 0 : "price is illegal";
            if (!validWeight(weight)) {
                throw new RuntimeException(fruitName + " " + GoodsStatus.WIGHT_IS_NEGATIVE.getDesc());
            }
//            检查这个商品是否在做活动，如果是那就拿到它的打折后的价格 否则就返回原价格
            BigDecimal promotionPrice = shopping.getGoodsPromotionPrice(fruitName, price);
            promotionPrice = promotionPrice.multiply(new BigDecimal(weight)).setScale(2, RoundingMode.HALF_UP);
            totalAmount = totalAmount.add(promotionPrice);
        }
        return totalAmount;
    }

    /**
     * @param weight 商品重量
     * @ author wdx
     * @desc 验证商品的重量是否合法
     */
    private boolean validWeight(Double weight) {
        return weight >= 0;
    }


    /**
     * @desc 内部商品信息设置 不对外提供修改
     * 用户生成当前超市可以售卖那些水果以及价格
     */
    public static class Shopping {
        //保存商品对应的价格
        private final HashMap<String, Integer> goods = new HashMap<>();
        //用户的购物车
        private final HashMap<String, Double> shoppingTrolley = new HashMap<>();

        // 保存促销活动的商品
        private final HashMap<String, Double> promotionGoods = new HashMap<>();

        public Shopping() {
            initGoods();
        }

        //        初始化水果信息
        private void initGoods() {
            for (FruitType fruit : FruitType.values()) {
                goods.put(fruit.getFruitName(), fruit.getPrice());
                if (fruit.isPromotion()) {//检查这个商品是否在促销活动中
                    promotionGoods.put(fruit.getFruitName(), fruit.getPromotionPrice());
                }
            }
        }

        public FruitSupermarket build() {

            return new FruitSupermarket(this);
        }

        //        用户购物调用的方法
        public Shopping buy(FruitType fruit, double weight) {
            assert weight > 0 : "weight can't be less than zero";
            shoppingTrolley.put(fruit.getFruitName(), weight);
            return this;
        }

        /**
         * @param price     商品原始的价格
         * @param fruitName 当前水果商品的名字
         * @author wdx
         * @desc 拿到此商品是否在促销 如果不是那么就返回原来价格
         */
        private BigDecimal getGoodsPromotionPrice(String fruitName, int price) {
            Double promotionPrice = promotionGoods.get(fruitName);
            BigDecimal currentPrice = new BigDecimal(price);
            if (promotionPrice == null) {
                return currentPrice;
            }
            return currentPrice.multiply(new BigDecimal(promotionPrice)).setScale(2, RoundingMode.HALF_UP);
        }

        private HashMap<String, Double> getShoppingTrolley() {
            return shoppingTrolley;
        }


        private Integer getFruitPrice(String fruitName) {
            return goods.get(fruitName);
        }
    }
}
